package com.yiwyn.aspect;


import com.yiwyn.annotation.Frequence;
import com.yiwyn.domain.Pair;
import com.yiwyn.utils.SpelUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.descriptor.InputSourceUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.aspectj.lang.reflect.SourceLocation;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.condition.RequestConditionHolder;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Aspect
@Component
public class FrequenceAspect {


    // 模拟缓存
    public List<String> cache = new ArrayList<>();

    @Around(value = "@annotation(frequence)")
    public Object around(ProceedingJoinPoint proceedingJoinPoint, Frequence frequence) throws Throwable {

        MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();


        String[] parameterNames = methodSignature.getParameterNames();
        Object[] args = proceedingJoinPoint.getArgs();
        List<Pair> pairs = new ArrayList<>();

        for (int i = 0; i < parameterNames.length; i++) {
            pairs.add(new Pair(parameterNames[i], args[i]));
        }

        String value = SpelUtil.getValue(frequence.id(), pairs);
        log.info("从spel表达式中获取的值为:{}", value);

        String cacheKey = frequence.uniPrefix() + value;
        if (!cache.contains(cacheKey)) {
            cache.add(cacheKey);
        } else {
            throw new Exception("暂时不能访问");
        }

        Object proceed;
        try {
            proceed = proceedingJoinPoint.proceed();
        } finally {
            cache.remove(cacheKey);
        }
        return proceed;
    }
}
